package com.railwayservice.messages.service;

import com.railwayservice.application.config.AppConfig;
import com.railwayservice.application.exception.AppException;
import com.railwayservice.application.util.JSonUtils;
import com.railwayservice.application.util.SendMSG;
import com.railwayservice.messages.dao.NoticeDao;
import com.railwayservice.messages.entity.Notice;
import com.railwayservice.messages.vo.OrderNotice;
import com.railwayservice.messages.vo.WechatTMessage;
import com.railwayservice.order.entity.MainOrder;
import com.railwayserviceWX.config.WeixinConfig;
import com.railwayserviceWX.controller.WechatAccessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 通知服务类。
 *
 * @author Ewing
 */
@Service
public class NoticeServiceImpl implements NoticeService {

    private final Logger logger = LoggerFactory.getLogger(NoticeServiceImpl.class);

    private NoticeDao noticeDao;

    @Autowired
    public void setNoticeDao(NoticeDao noticeDao) {
        this.noticeDao = noticeDao;
    }

    @Override
    @Transactional
    public Notice addNotice(Notice notice) {
        if (notice.getStatus() == null)
            notice.setStatus(MessagesStatic.NOTICE_STATUS_NOT_DEAL);
        logger.info("通知服务层：新增通知：通知内容：" + notice.getContent());
        notice.setCreateTime(new Date());
        return noticeDao.save(notice);
    }

    @Override
    public List<Notice> getNoticeByReceiverId(String receiverId) {
        if (!StringUtils.hasText(receiverId)) {
            throw new AppException("通知接收人的ID为空！");
        }
        logger.info("通知服务层：查询通知列表：接收人ID：" + receiverId);
        return noticeDao.getNoticeByReceiverId(receiverId);
    }

    @Override
    @Transactional
    public void deleteNoticeByReceiverId(String receiverId) {
        if (!StringUtils.hasText(receiverId))
            throw new AppException("请提供通知接收人的ID！");
        logger.info("通知服务层：删除通知：接收人ID：" + receiverId);
        List<Notice> listNotice = noticeDao.getNoticeByReceiverId(receiverId);
        if (0 == listNotice.size()) {
            return;
        }
        noticeDao.deleteInBatch(listNotice);
    }

    /**
     * 触发一条通知，不抛出异常。
     */
    @Override
    @Transactional
    public void sendOrderOverTime(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 保存通知到用户消息中
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* 发送通知给用户微信消息模板格式：
            {{first.DATA}}
             商品信息：{{keyword1.DATA}}
             订单金额：{{keyword2.DATA}}
             订单状态：{{keyword3.DATA}}
             {{remark.DATA}} */
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_CANCEL_AGREE;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "订单超时，系统自动退款。\n", "#FF6600")
                    .addData("keyword1", orderNotice.getProductDetail())
                    .addData("keyword2", "￥" + mainOrder.getOrderTotalPrice())
                    .addData("keyword3", orderNotice.getOrderStatusName())
                    .addData("remark", "\n您的订单10分钟内，无配送员接单，为不影响您的行程，已自动退款，如有时间欢迎再次下单。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 短信（SMS）通知用户取货。
     */
    @Override
    public void smsToUserGetGoods(MainOrder mainOrder) {
        SendMSG.sendGoodsDelivery(mainOrder.getCustomerPhoneNo(), mainOrder.getDeliverAddress());
    }

    /**
     * 发送收货验证码给用户微信。
     */
    @Override
    @Transactional
    public void sendReceiveCode(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                验证码：{{keyword1.DATA}}
                商品名称：{{keyword2.DATA}}
                商家名称：{{keyword3.DATA}}
                {{remark.DATA}} */
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_ORDER_PAY;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "订单已生成，等待配送。\n", "#FF6600")
                    .addData("keyword1", mainOrder.getReceiveCode())
                    .addData("keyword2", orderNotice.getProductDetail())
                    .addData("keyword3", orderNotice.getMerchantName())
                    .addData("remark", "\n您确认收货时，请将验证码告知对方。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送配送员已接单给用户微信。
     */
    @Override
    @Transactional
    public void sendServantAccept(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                订单编号：{{keyword1.DATA}}
                配送员姓名：{{keyword2.DATA}}
                配送员电话：{{keyword3.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_SERVANT_ACCEPT;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "配送员已成功接单。\n", "#FF6600")
                    .addData("keyword1", mainOrder.getOrderNo())
                    .addData("keyword2", orderNotice.getServantName())
                    .addData("keyword3", orderNotice.getServantPhoneNo())
                    .addData("remark", "\n请保持电话畅通。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送配送员已取货给用户微信。
     */
    @Override
    @Transactional
    public void sendServantGetGoods(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                商户名称：{{keyword1.DATA}}
                订单号：{{keyword2.DATA}}
                配送员姓名：{{keyword3.DATA}}
                配送员电话：{{keyword4.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_SERVANT_GET_GOODS;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "配送员已取货，订单正在配送中，请您保持电话通畅。\n", "#FF6600")
                    .addData("keyword1", orderNotice.getMerchantName())
                    .addData("keyword2", mainOrder.getOrderNo())
                    .addData("keyword3", orderNotice.getServantName())
                    .addData("keyword4", orderNotice.getServantPhoneNo())
                    .addData("remark", "\n如您有事需要更改配送地点，请及时与配送员联系。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送订单已完成给用户微信。
     */
    @Override
    @Transactional
    public void sendOrderComplete(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                订单详情：{{keyword1.DATA}}
                完成时间：{{keyword2.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_ORDER_COMPLETED;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "商品已送达，订单完成，感谢购买。\n", "#FF6600")
                    .addData("keyword1", orderNotice.getProductDetail())
                    .addData("keyword2", new SimpleDateFormat(AppConfig.DATE_TIME_FORMAT).format(mainOrder.getUpdateDate()))
                    .addData("remark", "\n点击本通知，对商家进行评价。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送申请取消订单消息给用户微信。
     */
    @Override
    @Transactional
    public void sendCancelApply(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                退款金额：{{orderProductPrice.DATA}}
                商品详情：{{orderProductName.DATA}}
                订单编号：{{orderName.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_CANCEL_APPLY;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "您已申请退款，等待对方确认。", "#FF6600") //该模板带有换行
                    .addData("orderProductPrice", "￥" + mainOrder.getOrderTotalPrice())
                    .addData("orderProductName", orderNotice.getProductDetail())
                    .addData("orderName", mainOrder.getOrderNo())
                    .addData("remark", "\n温馨提示：退款前请确保已联系配送员。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送配送员同意退款给用户微信。
     */
    @Override
    @Transactional
    public void sendCancelAgree(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                退款金额：{{keyword1.DATA}}
                商品名称：{{keyword2.DATA}}
                退款单号：{{keyword3.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_CANCEL_AGREE;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "您的订单已经完成退款。\n", "#FF6600")
                    .addData("keyword1", "￥" + mainOrder.getOrderTotalPrice())
                    .addData("keyword2", orderNotice.getProductDetail())
                    .addData("keyword3", mainOrder.getOrderNo())
                    .addData("remark", "\n退款金额原路退回到您的账户（零钱20分钟内到账；银行卡3个工作日左右）请留意查收。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

    /**
     * 发送配送员拒绝取消订单给用户微信。
     */
    @Override
    @Transactional
    public void sendCancelRefuse(MainOrder mainOrder) {
        logger.info("订单变动通知用户微信：订单ID：" + (mainOrder == null ? "" : mainOrder.getOrderId()));
        try {
            // 获取消息通知相关的属性
            OrderNotice orderNotice = noticeDao.getNoticeOrderInfo(mainOrder.getOrderId());
            orderNotice.setCreateTime(new Date());
            Notice notice = new Notice();
            String jsonNotice = JSonUtils.toJSon(orderNotice);
            logger.info("保存用户的消息通知：" + jsonNotice);
            notice.setContent(jsonNotice);
            notice.setReceiverId(mainOrder.getUserId());
            notice.setType(MessagesStatic.NOTICE_TYPE_MAIN_ORDER);
            this.addNotice(notice);

            /* {{first.DATA}}
                退款金额：{{orderProductPrice.DATA}}
                商品详情：{{orderProductName.DATA}}
                订单编号：{{orderName.DATA}}
                {{remark.DATA}}*/
            WechatTMessage message = new WechatTMessage();
            message.touser = orderNotice.getOpenid();
            message.template_id = WeixinConfig.MESSAGE_TEMPLATE_CANCEL_REFUSE;
            message.url = WeixinConfig.HOST + "/wechat/orderDetail.html?orderId=" + mainOrder.getOrderId() + "&userId=" + mainOrder.getUserId();
            message.addData("first", "您的退款申请被拒绝，请与对方协商沟通。", "#FF6600")
                    .addData("orderProductPrice", "￥" + mainOrder.getOrderTotalPrice())
                    .addData("orderProductName", orderNotice.getProductDetail())
                    .addData("orderName", mainOrder.getOrderNo())
                    .addData("remark", "\n拒绝理由：" + (mainOrder.getRefuseReason() == null ? "" : mainOrder.getRefuseReason())
                            + "\n如果双方无法协商一致，请联系客服：073183861339。", "#666666");

            // 发送通知给微信用户
            String jsonData = JSonUtils.toJSon(message);
            logger.info("发送通知给用户的微信：数据：" + jsonData);
            WechatAccessor.sendMessageToUser(jsonData);
        } catch (Exception e) {
            logger.error("订单变动通知用户微信异常：订单ID：" + (mainOrder == null ? "null" : mainOrder.getOrderId()), e);
        }
    }

}
